package main

import (
	"flag"
	"fmt"
	"log"
	"strings"
	"sync"

	"github.com/obs-data-process/internal/biz"
	"github.com/obs-data-process/internal/biz/domain"
	"github.com/obs-data-process/internal/pkg/config"
	"github.com/pkg/errors"
	"github.com/spf13/viper"
)

const (
	_defaultBucket       = "hotel"
	_defaultCfg          = "conf/app.yaml"
	_defaultBusinessType = 1 // 1: hotel 2: mall
	_defaultDataSource   = "./data.json"
)

var (
	bucket       string
	businessType int
	cfg          string
	dataFile     string
)

type App struct {
	imageService   *biz.ImageUserCase
	commandService *biz.CommandUserCase
}

func NewApp(imageService *biz.ImageUserCase, commandService *biz.CommandUserCase) *App {
	return &App{imageService: imageService, commandService: commandService}
}

func main() {
	flag.StringVar(&bucket, "bucket", _defaultBucket, "obs bucket name")
	flag.StringVar(&cfg, "c", _defaultCfg, "app config file")
	flag.StringVar(&dataFile, "ds", _defaultDataSource, "datasource")
	flag.IntVar(&businessType, "type", _defaultBusinessType, "business type 1:hotel 2:mall")
	flag.Parse()
	log.Printf("bucket:%s, business type: %d\n", bucket, businessType)

	err := config.Init(cfg)
	if err != nil {
		log.Fatal("load config failed", err)
	}

	app, cleanup, err := InitApp()
	if err != nil {
		log.Fatal("init image imageService failed", err)
	}
	defer cleanup()
	images, err := app.imageService.GetImages(dataFile)
	if err != nil {
		printErrorLog(err)
		return
	}

	var wg sync.WaitGroup
	commands, err := app.commandService.GetCommands(domain.BusinessType(businessType))
	//log.Printf("commands: %+v\n", commands)
	if err != nil {
		printErrorLog(err)
		return
	}

	wg.Add(len(images) * len(commands))
	for _, image := range images {
		split := strings.Split(image.Url, ".")
		filename := split[0]
		suffix := "." + split[1]
		for _, command := range commands {
			go func(imageUrl string, cmd domain.Command) {
				defer wg.Done()

				newObjectName := fmt.Sprintf("%s_%s%s", filename, cmd.Postfix, suffix)
				//log.Printf("newObjectName:%s\n", newObjectName)
				log.Printf("bucket: %s, imageUrl: %s, style: %s, objectName:%s\n", bucket, imageUrl, cmd.Style, newObjectName)
				url, err := app.imageService.GetTempSignatureUrl(bucket, imageUrl, cmd.Style, newObjectName)
				log.Printf("url:%s\n", url)
				if err != nil {
					printErrorLog(err)
					log.Printf("get temp signature url failed.")
				} else {
					log.Printf("%s%s\n", viper.GetString("obs.cdn"), newObjectName)
				}
			}(image.Url, command)

		}

	}

	wg.Wait()
	log.Println("All Done!")
}

func printErrorLog(err error) {
	log.Printf("%T %v \n , %+v", errors.Cause(err),errors.Cause(err), err)
}
